package com.hua.api.modules.express.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hua.api.core.constants.Status;
import com.hua.api.core.framework.annotation.Query;
import com.hua.api.core.framework.http.response.OpenApiResponse;
import com.hua.api.core.framework.util.exception.ApiError;
import com.hua.api.core.out.baidu.BaiduHelper;
import com.hua.api.core.out.express.ishansong.domain.IssStatus;
import com.hua.api.core.out.express.ishansong.domain.OrderCalculateParam;
import com.hua.api.core.out.express.ishansong.domain.Receiver;
import com.hua.api.core.out.express.ishansong.domain.Sender;
import com.hua.api.core.out.express.ishansong.request.*;
import com.hua.api.core.util.StringUtil;
import com.hua.api.core.util.ValidationUtil;
import com.hua.api.modules.express.dao.ExpressOrderDao;
import com.hua.api.modules.express.domain.ExpressOrder;
import com.hua.api.modules.express.domain.ShopInfoExpress;
import com.hua.api.modules.express.repository.ShopInfoExpressRepository;
import com.hua.api.modules.express.service.ExpressInfoService;
import com.hua.api.modules.express.service.dto.ExpressInfoCriteria;
import com.hua.api.modules.express.service.dto.ExpressOrderDto;
import com.hua.api.modules.express.util.ExpressOrderUtil;
import com.hua.api.modules.finance.domain.UserAccount;
import com.hua.api.modules.finance.service.UserAccountService;
import com.hua.api.modules.order.dao.ShopInfoDao;
import com.hua.api.modules.order.domain.OrderInfo;
import com.hua.api.modules.order.domain.ShopInfo;
import com.hua.api.modules.order.service.OrderInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * 闪送物流对接接口
 * */
@SuppressWarnings("all")
@Slf4j
@Component("ishansong")
public class IssExpressInfoServiceImpl implements ExpressInfoService {

    @Autowired
    public ShopInfoDao shopInfoDao;

    @Autowired
    public ExpressOrderDao expressOrderDao;

    @Autowired
    public ShopInfoExpressRepository shopInfoExpressRepository;

    @Autowired
    public OrderInfoService orderInfoService;

    @Autowired
    public UserAccountService userAccountService;

    @Override
    public JSONObject openCitiesLists() {
        return null;
    }

    @Override
    public JSONObject queryAllStores(ExpressInfoCriteria criteria) {
        QueryAllStoresRequest request = new QueryAllStoresRequest();
        request.setStoreId(criteria.getStoreId());
        request.setPageNo(criteria.getPageNo());
        request.setPageSize(criteria.getPageNo());
        OpenApiResponse response = request.doRequest();
        if(!response.isError){
            return response.toJSONObject();
        }else {
            throw ApiError.Type.LOGIC_ERROR.toException(response.errMsg);
        }
    }

    @Override
    public JSONObject storeOpertionSync(String storeId, String expressCode, Integer shopId) {
        QueryAllStoresRequest request = new QueryAllStoresRequest();
        request.setStoreId(storeId);
        OpenApiResponse response = request.doRequest();

        if(!response.isError){
            JSONObject result = response.toJSONObject();
            JSONArray array = result.getJSONArray("data");
            if(array.size()==0){
                throw ApiError.Type.LOGIC_ERROR.toException("未找到匹配的店铺参数！storeId="+storeId);
            }
            JSONObject data = array.getJSONObject(0);
            String address = data.getString("address");
            Double latitude = data.getDouble("latitude");
            Double longitude = data.getDouble("longitude");
            Integer goodType = data.getInteger("goodType");
            Integer cityId = data.getInteger("cityId");
            String storeId2 = data.getString("storeId");
            String addressDetail = data.getString("addressDetail");
            String cityName = data.getString("cityName");
            String storeName = data.getString("storeName");
            String contactsMobile = data.getString("contactsMobile");

            if(!StringUtil.equals(storeId2, storeId)){
                throw ApiError.Type.LOGIC_ERROR.toException("storeId数据不一致！");
            }

            ShopInfoExpress shopInfoExpress = shopInfoExpressRepository.findByStoreId(storeId);
            if(null!=shopInfoExpress){
                if(!StringUtil.equals(shopId, shopInfoExpress.getShopId())){
                    throw ApiError.Type.LOGIC_ERROR.toException("shopId数据不一致！");
                }
                log.info("更新 ShopInfoExpress storeId={}",storeId);
                shopInfoExpress.setStoreName(storeName);
                shopInfoExpress.setLatitude(latitude);
                shopInfoExpress.setLongitude(longitude);
                shopInfoExpress.setAddressDetail(addressDetail);
                shopInfoExpress.setCityName(cityName);
                shopInfoExpress.setAddress(address);
                shopInfoExpressRepository.save(shopInfoExpress);
            }else {
                ShopInfo shopInfo = shopInfoDao.getObject(ShopInfo.class, shopId);
                ValidationUtil.requireNotNull(shopInfo,"店铺信息不存在！");
                shopInfoExpress = new ShopInfoExpress();
                shopInfoExpress.setStoreId(storeId);
                shopInfoExpress.setShopId(shopId);
                shopInfoExpress.setAddressDetail(addressDetail);
                shopInfoExpress.setCityName(cityName);
                shopInfoExpress.setAddress(address);
                shopInfoExpress.setStoreName(storeName);
                shopInfoExpress.setLatitude(latitude);
                shopInfoExpress.setLongitude(longitude);
                shopInfoExpress.setCityCode(String.valueOf(cityId));
                shopInfoExpress.setContactsMobile(contactsMobile);
                shopInfoExpress.setExpressCode(expressCode);
                shopInfoExpress.setGeoType("baidu");
                shopInfoExpress.setGoodsType(goodType+"");
                shopInfoExpress.setStatus(Status.LOGIC_Y);
                shopInfoExpressRepository.save(shopInfoExpress);
            }

            return result;
        }else {
            throw ApiError.Type.LOGIC_ERROR.toException(response.errMsg);
        }
    }

    @Override
    public JSONObject getUserAccount() {
        GetUserAccountRequest request = new GetUserAccountRequest();
        OpenApiResponse response = request.doRequest();
        if(!response.isError){
            JSONObject result = response.toJSONObject();
            if(result.getInteger("status")!=200){
                throw ApiError.Type.LOGIC_ERROR.toException(result.getString("msg"));
            }
            JSONObject data = result.getJSONObject("data");
            return data;
        }else {

            throw ApiError.Type.LOGIC_ERROR.toException(response.errMsg);
        }
    }

    @Override
    public ExpressOrder orderCalculate(ShopInfoExpress express, OrderInfo order, UserAccount account,Integer isSaleAfter) {
        log.info("IssExpressInfoServiceImpl.orderCalculate(orderId={})",order.getId());
        ExpressOrder eorder = ExpressOrderUtil.getExpressOrder(express,order);
        eorder.setIsSaleAfter(isSaleAfter); // 是否售后单

        OrderCalculateRequest request = new OrderCalculateRequest();
        OrderCalculateParam param = new OrderCalculateParam();

        param.setCityName(eorder.getCityName());
        param.setStoreId(eorder.getStoreId());
        param.setAppointType(eorder.getAppointType());  //0立即单，1预约单

        // 美团 电话格式  18518144606_9880 需要转成闪送的 18518144606#9880格式
        String fromMobile = StringUtil.dealNull(eorder.getFromMobile().replaceAll("_","#"));
        // 饿了么 电话格式  8400668090,196 需要转成闪送的 18518144606#9880格式
        fromMobile = StringUtil.dealNull(fromMobile.replaceAll(",","#"));

        Sender sender = new Sender();
        sender.setFromAddress(eorder.getFromAddress());
        sender.setFromAddressDetail(eorder.getFromAddressDetail());
        sender.setFromMobile(fromMobile);
        sender.setFromSenderName(eorder.getFromSenderName());

        Double lat = eorder.getFromLatitude();
        Double lng = eorder.getFromLongitude();
        // 高德地图转百度 闪送要求百度坐标
        if(StringUtil.equals("gaode",eorder.getFromGeoType())){
            // 坐标转换
            JSONObject data = BaiduHelper.changeGeoToBaidu(lat,lng);
            lat = data.getDouble("lat");
            lng = data.getDouble("lng");
        }

        sender.setFromLatitude(String.valueOf(lat));
        sender.setFromLongitude(String.valueOf(lng));
        // 发件人
        param.setSender(sender);
        // 接收用户
        Receiver receiver = new Receiver();

        // 美团 电话格式  18518144606_9880 需要转成闪送的 18518144606#9880格式
        String toMobile = StringUtil.dealNull(eorder.getToMobile().replaceAll("_","#"));
        // 饿了么 电话格式  8400668090,196 需要转成闪送的 18518144606#9880格式
        toMobile = StringUtil.dealNull(toMobile.replaceAll(",","#"));

        receiver.setToMobile(toMobile);
        receiver.setToReceiverName(eorder.getToReceiveName());
        receiver.setToAddress(eorder.getToAddress());
        receiver.setOrderNo(eorder.getExpressOrderNo());
        Double toLat = eorder.getToLatitude();// order.getLatitude();
        Double toLng = eorder.getToLongitude();
        // 高德地图转百度地图坐标
        // x 经度longitude  y 维度 latitude
        if(!StringUtil.equals("baidu",eorder.getToGeoType())){
            JSONObject data = BaiduHelper.changeGeoToBaidu(toLat,toLng);
            receiver.setToLongitude(data.getString("lng"));
            receiver.setToLatitude(data.getString("lat"));
        }else{
            receiver.setToLongitude(String.valueOf(toLng));
            receiver.setToLatitude(String.valueOf(toLat));
        }
        receiver.setGoodType(7); //鲜花绿植
        receiver.setWeight(1);

        String daySeq = StringUtil.dealNull(order.getDaySeq(),"0");
        // receiver.setRemarks("取单请报序号["+daySeq+"] 或者单号："+daySeq+"]");
        receiver.setRemarks("取单请报序号:"+daySeq+" 与单号："+order.getId());
        List<Receiver> receivers = new ArrayList<>();
        receivers.add(receiver);
        param.setReceiverList(receivers);

        request.setCalculateParam(param);
        OpenApiResponse response = request.doRequest();

        if(!response.isError){
            // System.out.println("-------"+response.toJSONObject().toString());
            JSONObject result = response.toJSONObject();
            if(result.getInteger("status")!=200){
                throw ApiError.Type.LOGIC_ERROR.toException(result.getString("msg"));
            }
            JSONObject data = result.getJSONObject("data");
            eorder.setThirdOrderNo(data.getString("orderNumber")); // 三方订单号
            eorder.setTotalAmount(data.getInteger("totalAmount")); // 订单总金额
            eorder.setDynamicFee(data.getInteger("dynamicSubsidyAmount")); // 订单补贴
            eorder.setRealFee(data.getInteger("totalFeeAfterSave")); // 实际支付费用
            eorder.setEstimateGrabSecond(data.getInteger("estimateGrabSecond")); //预计接单时长
            eorder.setEstimateReceiveSecond(data.getInteger("estimateReceiveSecond")); // 预计完单时长
            eorder.setDistance(data.getInteger("totalDistance")); // 配送距离
            eorder.setChargeSource(Status.CHARGE_HUAYT);
            // 账户余额判断
            if(account.getAmountMoney()<eorder.getRealFee()/100d){
                throw ApiError.Type.EXPRESS_API_ERROR.toException("您的账户余额不足 userId:"+account.getUserId());
            }
        }else {
            // System.out.println("2-------"+response.toJSONObject().toString());
            throw ApiError.Type.LOGIC_ERROR.toException(response.errMsg);
        }

        return eorder;
    }

    @Override
    public ExpressOrder orderPlace(ExpressOrder eorder) {
        OrderPlaceRequest request = new OrderPlaceRequest();
        request.setIssOrderNo(eorder.getThirdOrderNo());
        OpenApiResponse response = request.doRequest();
        if(!response.isError){
            JSONObject result = response.toJSONObject();
            if(result.getInteger("status")!=200){
                throw ApiError.Type.LOGIC_ERROR.toException(result.getString("msg"));
            }
            JSONObject data = result.getJSONObject("data");
            eorder.setTotalAmount(data.getInteger("totalAmount")); // 订单总金额
            eorder.setDynamicFee(data.getInteger("dynamicSubsidyAmount")); // 订单补贴
            eorder.setRealFee(data.getInteger("totalFeeAfterSave")); // 实际支付费用
            eorder.setEstimateGrabSecond(data.getInteger("estimateGrabSecond")); //预计接单时长
            eorder.setEstimateReceiveSecond(data.getInteger("estimateReceiveSecond")); // 预计完单时长
            eorder.setDistance(data.getInteger("totalDistance")); // 配送距离
            return eorder;
        }else {
            throw ApiError.Type.LOGIC_ERROR.toException(response.errMsg);
        }

    }

    @Override
    public JSONObject courierInfo(ExpressInfoCriteria criteria) {
        return null;
    }

    @Override
    public JSONObject abortOrder(ExpressInfoCriteria criteria) {
        ExpressOrder eorder = expressOrderDao.findByExpressOrderNo(criteria.getExpressOrderNo());
        ValidationUtil.requireNotNull(eorder,"物流单信息不存在！");

        AbortOrderRequest request = new AbortOrderRequest();
        request.setIssOrderNo(eorder.getThirdOrderNo());
        request.setDeductFlag(true);
        OpenApiResponse response = request.doRequest();

        if(!response.isError){
            JSONObject result = response.toJSONObject();
            if(result.getInteger("status")!=200){
                throw ApiError.Type.LOGIC_ERROR.toException(result.getString("msg"));
            }
            JSONObject data = result.getJSONObject("data");
            Integer deductAmount = data.getInteger("deductAmount"); // 扣款金额(分)
            Integer abortType = data.getInteger("abortType"); // 取消发起人，详见下放枚举
            Integer punishType = data.getInteger("punishType");
            String abortReason = data.getString("abortReason");
            Integer sendBackFee = data.getInteger("sendBackFee"); // 返回费用(分) 送回费，单位：分（取件后取消订单，当取消费大于订单实付金额时，会产生送回费，需用户额外支付）
            return data;
        }else {

            throw ApiError.Type.LOGIC_ERROR.toException(response.errMsg);
        }

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public JSONObject addition(ExpressOrder eorder, Integer fenMoney) {

        AdditionRequest request = new AdditionRequest();
        request.setIssOrderNo(eorder.getThirdOrderNo());
        request.setAdditionAmount(fenMoney);
        OpenApiResponse response = request.doRequest();
        if(!response.isError){
            JSONObject result = response.toJSONObject();
            if(result.getInteger("status")!=200){
                throw ApiError.Type.LOGIC_ERROR.toException(result.getString("msg"));
            }
            return result;
        }else {
            throw ApiError.Type.LOGIC_ERROR.toException(response.errMsg);
        }

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public JSONObject storeOperationAdd(Integer shopId,String expressCode) {
        log.info("IssExpressInfoServiceImpl.storeOperationAdd(shopId={},expressCode={})",shopId,expressCode);
        ShopInfo shopInfo = shopInfoDao.getObject(ShopInfo.class, shopId);
        ValidationUtil.requireNotNull(shopInfo,"店铺数据不存在！ shopId="+shopId);
        StoreOperationRequest request = new StoreOperationRequest();
        request.setStoreName(shopInfo.getShopName());
        request.setPhone(shopInfo.getPhoneNumber());
        request.setAddress(shopInfo.getTown());
        request.setAddressDetail(shopInfo.getShopAddress());
        request.setCityName(shopInfo.getCity());
        request.setGoodType("7"); //鲜花
        request.setOperationType("1");
        request.setLongitude(StringUtil.dealNull(shopInfo.getBdLongitude()));
        request.setLatitude(StringUtil.dealNull(shopInfo.getBdLatitude()));
        OpenApiResponse response = request.doRequest();
        log.info(response.toJSONObject().toString());
        JSONObject result =response.toJSONObject();
        if(result.getInteger("status")==200){
            String storeId = result.getString("data");
            log.info("保存物流店铺信息 storeId={}",storeId);
            ShopInfoExpress shopInfoExpress = new ShopInfoExpress();
            shopInfoExpress.setShopId(shopId);
            shopInfoExpress.setStoreId(storeId);
            shopInfoExpress.setExpressCode(expressCode);
            shopInfoExpress.setStoreName(shopInfo.getShopName());
            shopInfoExpress.setAddress(shopInfo.getTown());
            shopInfoExpress.setCityName(shopInfo.getCity());
            shopInfoExpress.setAddressDetail(shopInfo.getShopAddress());
            shopInfoExpress.setLatitude(shopInfo.getBdLatitude());
            shopInfoExpress.setLongitude(shopInfo.getBdLongitude());
            shopInfoExpress.setGeoType("baidu");
            shopInfoExpress.setStatus(1);
            shopInfoExpress.setContactsMobile(shopInfo.getPhoneNumber());
            shopInfoDao.saveObject(shopInfoExpress);
        }
        return new JSONObject();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public JSONObject storeOperationModify(Integer shopId,String expressCode,String storeId) {
        log.info("IssExpressInfoServiceImpl.storeOperationAdd(shopId={},expressCode={})",shopId,expressCode);
        ShopInfoExpress exp = shopInfoExpressRepository.findByStoreId(storeId);
        ValidationUtil.requireNotNull(exp,"店铺数据不存在！ shopId="+shopId);
        ShopInfo shopInfo = shopInfoDao.getObject(ShopInfo.class, shopId);
        ValidationUtil.requireNotNull(shopInfo,"店铺数据不存在！ shopId="+shopId);


        StoreOperationRequest request = new StoreOperationRequest();
        request.setStoreId(storeId);
        request.setStoreName(shopInfo.getShopName());
        request.setPhone(shopInfo.getPhoneNumber());
        request.setAddress(shopInfo.getTown());
        request.setAddressDetail(shopInfo.getShopAddress());
        request.setCityName(shopInfo.getCity());
        request.setGoodType("7"); //鲜花
        request.setOperationType("2");
        request.setLongitude(StringUtil.dealNull(shopInfo.getBdLongitude()));
        request.setLatitude(StringUtil.dealNull(shopInfo.getBdLatitude()));
        OpenApiResponse response = request.doRequest();
        if(!response.isError){
            log.info(response.toJSONObject().toString());

            exp.setStoreName(shopInfo.getShopName());
            exp.setAddress(shopInfo.getTown());
            exp.setAddressDetail(shopInfo.getShopAddress());
            exp.setContactsMobile(shopInfo.getPhoneNumber());
            exp.setLatitude(shopInfo.getBdLatitude());
            exp.setLongitude(shopInfo.getBdLongitude());
            exp.setCityName(shopInfo.getCity());
            shopInfoExpressRepository.save(exp);

            return new JSONObject();
        }else{
            throw ApiError.Type.LOGIC_ERROR.toException(response.errMsg);
        }
    }

    // http://open.ishansong.com/joinGuide/294
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void onOrderStatusChange(JSONObject data) {

        log.info("IssExpressInfoServiceImpl.onOrderStatusChange data={}",data.toString());
        Integer status = data.getInteger("status");
        String issOrderNo = data.getString("issOrderNo");
        IssStatus issStatus = IssStatus.fromValue(status);
        log.info("onOrderStatusChange issOrderNo={} statusName={}",issOrderNo,issStatus.name());
        ExpressOrder expressOrder = expressOrderDao.findUseThirdOrderNo(issOrderNo);
        ValidationUtil.requireNotNull(expressOrder,"物流单号不存在！ issOrderNo="+issOrderNo);
        if(issStatus == IssStatus.paidan){
            // 20 商户已经支付，订单分配给配送员（subStatus为1，表示派单中；subStatus为2，表示转单改派中）

            Integer subStatus = data.getInteger("subStatus");
            onExpressOrderPaidan(expressOrder,data,subStatus);

        }else if(issStatus == IssStatus.daiquhuo){
            // 30 配送员已经接单（subStatus为1，表示待取货；subStatus为2，表示已就位）
            onExpressOrderJiedan(expressOrder,data);
        }else if(issStatus == IssStatus.peisongzhong){
            // 40 已经取件，配送中（subStatus为1，表示闪送中；subStatus为2，申请取消中；subStatus为3，物品送回中；subStatus为4，取消单客服介入中）
            onExpressOrderPeisong(expressOrder,data);
        }else if(issStatus == IssStatus.yisongda){
            // 50 已经配送完成（subStatus为1：已完成；subStatus为2：已退款；）
            onExpressOrderSongda(expressOrder,data);
        }else if(issStatus == IssStatus.quxiao){
            // 60 已经取消订单
            onExpressOrderQuxiao(expressOrder,data);
        }
    }

    // 派单中
    @Transactional(rollbackFor = Exception.class)
    private void onExpressOrderPaidan(ExpressOrder expressOrder,JSONObject data,Integer subStatus){
        log.info("物流单开始配送 onExpressOrderPaidan={},subStatus={}",expressOrder.getThirdOrderNo(),subStatus);
        Status.LogisticsStatus logisticsStatus = Status.LogisticsStatus.fromValue(expressOrder.getOrderStatus());
        if(subStatus == 2){
            // 转派单中
            log.info("物流单开始配送，物流转派单 thirdOrderNo={}",expressOrder.getThirdOrderNo());
            expressOrder.setOrderStatus(Status.LogisticsStatus.daijiedan.getValue());
            expressOrderDao.updateObject(expressOrder);
            OrderInfo orderInfo = expressOrderDao.getObject(OrderInfo.class,expressOrder.getOrderId());
            // 非售后订单则修改订单的配送状态。
            if(null!=orderInfo && StringUtil.equals(expressOrder.getIsSaleAfter(),Status.LOGIC_N)){
                orderInfoService.onOrderInfoSendPaidan(orderInfo.getOrderNo(),expressOrder.getId().intValue());
            }
        }else if(logisticsStatus == Status.LogisticsStatus.daipeisong || logisticsStatus == Status.LogisticsStatus.yiquxiao){
            log.info("物流单开始配送，物流接单 thirdOrderNo={}",expressOrder.getThirdOrderNo());
            expressOrder.setOrderStatus( Status.LogisticsStatus.daijiedan.getValue());
            expressOrderDao.updateObject(expressOrder);
            OrderInfo orderInfo = expressOrderDao.getObject(OrderInfo.class,expressOrder.getOrderId());
            if(null!=orderInfo && !StringUtil.equals(expressOrder.getIsSaleAfter(),Status.LOGIC_Y)){
                orderInfoService.onOrderInfoSendPaidan(orderInfo.getOrderNo(),expressOrder.getId().intValue());
            }
        }
    }

    // 已接单
    @Transactional(rollbackFor = Exception.class)
    private void onExpressOrderJiedan(ExpressOrder expressOrder,JSONObject data){
        log.info("物流单开始配送 onExpressOrderJiedan={}",expressOrder.getThirdOrderNo());
        Status.LogisticsStatus logisticsStatus = Status.LogisticsStatus.fromValue(expressOrder.getOrderStatus());
        if(logisticsStatus == Status.LogisticsStatus.daijiedan || logisticsStatus == Status.LogisticsStatus.daipeisong ){
            log.info("物流单已接单，待取货 thirdOrderNo={}",expressOrder.getThirdOrderNo());
            expressOrder.setOrderStatus( Status.LogisticsStatus.yijiedan.getValue());
            JSONObject courier = data.getJSONObject("courier");
            String name = courier.getString("name");
            String mobile = courier.getString("mobile");
            String latitude = courier.getString("latitude");
            String longitude = courier.getString("longitude");
            // 配送员信息
            expressOrder.setCourierName(name);
            expressOrder.setCourierMobile(mobile);
            expressOrderDao.updateObject(expressOrder);
            OrderInfo orderInfo = expressOrderDao.getObject(OrderInfo.class,expressOrder.getOrderId());
            if(null!=orderInfo && !StringUtil.equals(expressOrder.getIsSaleAfter(),Status.LOGIC_Y)){
               orderInfoService.onOrderInfoSendJiedan(orderInfo.getOrderNo(),name,mobile);
            }
        }
    }

    // 配送中 已经取件，配送中（subStatus为1，表示闪送中；subStatus为2，申请取消中；subStatus为3，物品送回中；subStatus为4，取消单客服介入中）
    @Transactional(rollbackFor = Exception.class)
    private void onExpressOrderPeisong(ExpressOrder expressOrder,JSONObject data){
        log.info("物流单开始配送 onExpressOrderJiedan={}",expressOrder.getThirdOrderNo());
        Status.LogisticsStatus logisticsStatus = Status.LogisticsStatus.fromValue(expressOrder.getOrderStatus());

        if(logisticsStatus == Status.LogisticsStatus.daipeisong ||
                logisticsStatus == Status.LogisticsStatus.daijiedan ||
                logisticsStatus == Status.LogisticsStatus.yijiedan){
            log.info("物流单已接单，待取货 thirdOrderNo={}",expressOrder.getThirdOrderNo());
            expressOrder.setOrderStatus( Status.LogisticsStatus.peisongzhong.getValue());
            expressOrderDao.updateObject(expressOrder);

            OrderInfo orderInfo = expressOrderDao.getObject(OrderInfo.class,expressOrder.getOrderId());
            if(null!=orderInfo && StringUtil.equals(expressOrder.getIsSaleAfter(),Status.LOGIC_N)){
                orderInfoService.onOrderInfoSendPeisong(orderInfo.getOrderNo());
            }

        }
    }

    // 已送达  已经配送完成（subStatus为1：已完成；subStatus为2：已退款；）
    @Transactional(rollbackFor = Exception.class)
    private void onExpressOrderSongda(ExpressOrder expressOrder,JSONObject data){
        Integer subStatus = data.getInteger("subStatus");
        log.info("物流单开始配送 onExpressOrderJiedan={},subStatus={}",expressOrder.getThirdOrderNo(),subStatus);
        Status.LogisticsStatus logisticsStatus = Status.LogisticsStatus.fromValue(expressOrder.getOrderStatus());
        if(logisticsStatus == Status.LogisticsStatus.daipeisong ||
                logisticsStatus == Status.LogisticsStatus.daijiedan ||
                logisticsStatus == Status.LogisticsStatus.yijiedan ||
                logisticsStatus == Status.LogisticsStatus.peisongzhong){
            log.info("物流单已接单，待取货 thirdOrderNo={}",expressOrder.getThirdOrderNo());
            expressOrder.setOrderStatus( Status.LogisticsStatus.yisongda.getValue());
            expressOrderDao.updateObject(expressOrder);
            OrderInfo orderInfo = expressOrderDao.getObject(OrderInfo.class,expressOrder.getOrderId());

            // 已经配送完成（subStatus为1：已完成；
            if(null!=orderInfo && !StringUtil.equals(expressOrder.getIsSaleAfter(),Status.LOGIC_Y) && subStatus==1){
                orderInfoService.onOrderInfoSendSongda(orderInfo.getOrderNo());
            }
        }
    }

    // 已取消
    @Transactional(rollbackFor = Exception.class)
    private void onExpressOrderQuxiao(ExpressOrder expressOrder,JSONObject data){
        log.info("物流单取消 onExpressOrderQuxiao={}",expressOrder.getThirdOrderNo());
        Status.LogisticsStatus logisticsStatus = Status.LogisticsStatus.fromValue(expressOrder.getOrderStatus());
        if(logisticsStatus == Status.LogisticsStatus.daijiedan ||
                logisticsStatus == Status.LogisticsStatus.yijiedan ||
                logisticsStatus == Status.LogisticsStatus.peisongzhong){
            log.info("物流单已取消 thirdOrderNo={}",expressOrder.getThirdOrderNo());

            OrderInfo orderInfo = expressOrderDao.getObject(OrderInfo.class,expressOrder.getOrderId());
            if(null!=orderInfo && !StringUtil.equals(expressOrder.getIsSaleAfter(),Status.LOGIC_Y)){
                orderInfoService.onOrderInfoSendQuxiao(orderInfo.getOrderNo());
            }

            Integer backFee = expressOrder.getRealFee()-expressOrder.getPunishAmount(); // 支付金额-取消罚金
            Double backYuan = backFee/100d; // (元)
            log.info(" onExpressOrderQuxiao 取消配送，返回费用 backYuan={}元",backYuan);

            // 退款操作
            if(null!=orderInfo && expressOrder.getBackFee()==0){
                if(backYuan>0){
                    userAccountService.onUserAccountAddUseShopId(orderInfo.getShopId(),backYuan,"express_order","取消物流返回费用，单号:"+expressOrder.getExpressOrderNo());
                    expressOrder.setBackFee(backFee);
                }
            }

            expressOrder.setOrderStatus(Status.LogisticsStatus.yiquxiao.getValue());
            expressOrderDao.updateObject(expressOrder);

        }else {


            OrderInfo orderInfo = expressOrderDao.getObject(OrderInfo.class,expressOrder.getOrderId());
            if(null!=orderInfo && expressOrder.getBackFee()==0 ){
                Integer backFee = expressOrder.getRealFee()-expressOrder.getPunishAmount(); // 支付金额-取消罚金
                Double backYuan = backFee/100d; // (元)

                log.info(" onExpressOrderQuxiao 取消配送，返回费用 backYuan={}元",backYuan);
                if(backYuan>0){
                    userAccountService.onUserAccountAddUseShopId(orderInfo.getShopId(),backYuan,"express_order","取消物流返回费用，单号:"+expressOrder.getExpressOrderNo());
                    expressOrder.setBackFee(backFee);
                    expressOrderDao.updateObject(expressOrder);

                }
            }

        }






    }




}
